import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import label_binarize
from sklearn import metrics

## 设置字符集，防止中文乱码
mpl.rcParams['font.sans-serif']=[u'simHei']
mpl.rcParams['axes.unicode_minus']=False

def parse_record(columns,record):
    result=[]
    r=zip(columns,record)
    for column,value in r:
        if column=='cla':
          if value=='Iris-setosa':
              result.append(1)
          elif value=='Iris-versicolor':
              result.append(2)
          elif value=='Iris-virginica':
              result.append(3)
          else:
              result.append(np.nan)
        else:
          result.append(float(value))
    return result

def run():
    ## 数据加载
    path = '../data/iris.data'
    columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'cla']
    df = pd.read_csv(path, names=columns)

    ### 1. 数据转换为数字以及分割
    ## 数据转换
    datas=df.apply(lambda r: parse_record(columns, r), axis=1)
    ## 异常数据删除
    datas=datas.dropna(how='any')
    ## 数据分割
    X=datas[columns[0:-1]]
    Y=datas[columns[-1]]
    ## 数据抽样(训练数据和测试数据分割)
    X_train,X_test,Y_train,Y_test=train_test_split(X,Y,train_size=0.4,random_state=0)
    ##### KNN算法实现
    # a. 模型构建
    knc=KNeighborsClassifier(n_neighbors=3)
    knc.fit(X_train,Y_train)
    # b. 模型效果输出
    ## 将正确的数据转换为矩阵形式
    Y_test_hot=label_binarize(Y_test,classes=(1,2,3))
    ## 得到预测的损失值
    Y_score=knc.predict_proba(X_test)
    ## 计算roc的值
    knc_fpr,knc_tpr,knn_threasholds=metrics.roc_curve(Y_test_hot.ravel(),Y_score.ravel())
    ## 计算auc的值
    knc_auc=metrics.auc(knc_fpr,knc_tpr)
    print("KNN算法R值：", knc.score(X_train, Y_train))
    print("KNN算法AUC值：", knc_auc)
    # c. 模型预测
    Y_predict=knc.predict(X_test)
    ## 画图2：预测结果画图
    X_test_len=range(len(X_test))
    plt.figure(figsize=(12,6),facecolor='w')
    plt.ylim(0.5,3.5)
    plt.plot(X_test_len,Y_test,'ro',markersize=6,zorder=3,label=u'真实值')
    plt.plot(X_test_len,Y_predict,'yo',markersize=16,zorder=1,label=u'KNN算法预测值,R^2=%.3f' %knc.score(X_test,Y_test))
    plt.legend(loc='lower right')
    plt.xlabel(u'数据编号',fontsize=18)
    plt.ylabel(u'种类',fontsize=18)
    plt.title(u'鸢尾花数据分类',fontsize=20)
    plt.show()


run()